package com.zhihaoliang.animationtrain.animator

import android.animation.*
import android.content.Context
import android.graphics.*
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.OvalShape
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import com.zhihaoliang.animationtrain.R
import com.zhihaoliang.animationtrain.annotation.Info
import com.zhihaoliang.animationtrain.util.ShapeHolder

@Info(title = "属性动画演示弹跳的球", desc = "属性动画弹跳的球，演示背景颜色的变化和弹跳的球")
class BouncingBallsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.animator_activity_bouncing_balls)

        val container = findViewById<LinearLayout>(R.id.animator_containner)
        container.addView(AnimationView(this))

    }

    private class AnimationView(context: Context) : View(context) {

        private val balls:MutableList<ShapeHolder> = ArrayList()

        init {
            val colorAnim = ObjectAnimator.ofInt(this,
                "backgroundColor", Color.WHITE, Color.BLACK)
            colorAnim.duration = 5000
            colorAnim.setEvaluator(ArgbEvaluator())
            colorAnim.repeatCount = ValueAnimator.INFINITE
            colorAnim.repeatMode = ValueAnimator.REVERSE
            colorAnim.start()
        }

        override fun onTouchEvent(event: MotionEvent): Boolean {
            if(event.action != MotionEvent.ACTION_DOWN && event.action != MotionEvent.ACTION_MOVE) return false

            val shapeHolder = addBall(event.x,event.y)

            /**
             * 下落的动画
             */
           val startY =  shapeHolder.x
            val endY = height -50f
            val h = height.toFloat()
            val eventY = event.y
            val duration = (500 * ((h - eventY) / h)).toInt()
            val bounceAnim: ValueAnimator = ObjectAnimator.ofFloat(shapeHolder, "y", startY, endY)
            bounceAnim.duration = duration.toLong()
            bounceAnim.interpolator = AccelerateInterpolator()

            /**
             * 挤压动画 画的位置向左移动25f
             */
            val squashAnim1: ValueAnimator = ObjectAnimator.ofFloat(
                shapeHolder, "x", shapeHolder.x,
                shapeHolder.x - 25f
            )
            squashAnim1.duration = duration / 4.toLong()
            squashAnim1.repeatCount = 1
            squashAnim1.repeatMode = ValueAnimator.REVERSE
            squashAnim1.interpolator = DecelerateInterpolator()

            /**
             * 挤压动画 宽度变大
             */
            val squashAnim2: ValueAnimator = ObjectAnimator.ofFloat(
                shapeHolder, "width", shapeHolder.width,
                shapeHolder.width + 50
            )
            squashAnim2.duration = duration / 4.toLong()
            squashAnim2.repeatCount = 1
            squashAnim2.repeatMode = ValueAnimator.REVERSE
            squashAnim2.interpolator = DecelerateInterpolator()

            /**
             * 挤压操作，Y轴向下移动
             */
            val stretchAnim1: ValueAnimator = ObjectAnimator.ofFloat(
                shapeHolder, "y", endY,
                endY + 25f
            )
            stretchAnim1.duration = duration / 4.toLong()
            stretchAnim1.repeatCount = 1
            stretchAnim1.interpolator = DecelerateInterpolator()
            stretchAnim1.repeatMode = ValueAnimator.REVERSE

            /**
             * 挤压操作，Y轴高度变小
             */
            val stretchAnim2: ValueAnimator = ObjectAnimator.ofFloat(
                shapeHolder, "height",
                shapeHolder.height, shapeHolder.height - 25
            )
            stretchAnim2.duration = duration / 4.toLong()
            stretchAnim2.repeatCount = 1
            stretchAnim2.interpolator = DecelerateInterpolator()
            stretchAnim2.repeatMode = ValueAnimator.REVERSE

            /**
             * 回弹操作
             */
            val bounceBackAnim: ValueAnimator = ObjectAnimator.ofFloat(
                shapeHolder, "y", endY,
                startY
            )
            bounceBackAnim.duration = duration.toLong()
            bounceBackAnim.interpolator = DecelerateInterpolator()

            val bouncer = AnimatorSet()
            bouncer.play(bounceAnim).before(squashAnim1)
            bouncer.play(squashAnim1).with(squashAnim2)
            bouncer.play(squashAnim1).with(stretchAnim1)
            bouncer.play(squashAnim1).with(stretchAnim2)
            bouncer.play(bounceBackAnim).after(stretchAnim2)

            val fadeAnim: ValueAnimator = ObjectAnimator.ofFloat(shapeHolder, "alpha", 1f, 0f)
            fadeAnim.duration = 250
            fadeAnim.addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    balls.remove((animation as ObjectAnimator).target)
                }
            })

            val animatorSet = AnimatorSet()
            animatorSet.play(bouncer).before(fadeAnim)

            animatorSet.start()
            return true
        }

        private fun addBall(x: Float,y:Float):ShapeHolder{
            val circle = OvalShape()
            circle.resize(50F,50F)
            val shapeDrawable = ShapeDrawable(circle)

            val shapeHolder = ShapeHolder(shapeDrawable)
            shapeHolder.x = x -25F
            shapeHolder.y = y - 25F

            val red =  (Math.random()*255).toInt()
            val green = (Math.random()*255).toInt()
            val blue = (Math.random()*255).toInt()
            val color = -0x1000000 or (red shl 16) or (green shl 8) or blue
            val paint: Paint = shapeDrawable.paint
            val darkColor = -0x1000000 or (red / 4 shl 16) or (green / 4 shl 8) or blue / 4
            val gradient =RadialGradient(25f,25f,50f,color,darkColor,
                Shader.TileMode.CLAMP)
            paint.shader = gradient
            shapeHolder.paint = paint

            balls.add(shapeHolder)
            return shapeHolder
        }

        override fun onDraw(canvas: Canvas) {
           for(ball in balls){
               //保存当前的绘图状态 相当于先绘制到内存
               canvas.save()
                //移动到画的位置
               canvas.translate(ball.x, ball.y)
               ball.shapeDrawable.draw(canvas)
               //恢复之前保存的绘图状态
               canvas.restore()
           }
        }
    }
}
